'************************************************************************************
' Copyright © 2003-2005 Kathleen Dollard
'
' This software is provided 'as-is', without any express or implied warranty. In no 
' event will the author be held liable for any damages arising from the use of this
' software.
' 
' You may use this software for any purpose, including commercial applications, 
' and you may redistribute this software as part of application delivery: however, 
' this copyright notice may not be removed and you may not otherwise redistribute 
' this software directly other than providing a link to wwww.gendotnet.com. 
'
' You may alter this software to better server your needs (I'd like to hear about your 
' changes in order to make the software better). If you alter the softwre, you must  
' clearly mark it as altered and must not be misrepresented as the original software.
' nor wholly your original work.
'*************************************************************************************
Option Strict On
Option Explicit On 

Imports System

Namespace KADGen.CodeGenerationSupport
   Public Class RunUtility
      'Public Delegate Function GenerateDelegate( _
      '            ByVal outputFileName As String, _
      '            ByVal nsmgr As Xml.XmlNamespaceManager, _
      '            ByVal node As Xml.XmlNode, _
      '            ByVal nodeSelect As Xml.XmlNode) _
      '            As IO.Stream
      Private mProjectSettings As ProjectSettings
      Private mSourceControl As Utility.SourceControlBase

      Public Shared Function MaxStatus( _
               ByVal status1 As OutputStatus, _
               ByVal status2 As OutputStatus) _
               As OutputStatus
         If status1 > status2 Then
            Return status1
         Else
            Return status2
         End If
      End Function

      Public Sub New( _
               ByVal projectSettings As ProjectSettings, _
               ByVal sourceControl As Utility.SourceControlBase)
         mProjectSettings = projectSettings
         mSourceControl = sourceControl
      End Sub

      'Public Function ShouldRun( _
      '               ByVal outputFileName As String, _
      '               ByVal node As Xml.XmlNode, _
      '               ByVal statusoutput As IStatusOutput) _
      '               As Boolean
      '   If node.Name.ToLower = "kg:runsqlscripts" Then
      '      statusoutput.AddStatusInfo("RunUtility.ShouldRun", VerboseLevel.Obnoxious, _
      '              "Nested script ShouldRun tested later for " & outputFileName)
      '      Return True
      '   ElseIf node.Name.ToLower = "kg:processnodeset" Then
      '      statusoutput.AddStatusInfo("RunUtility.ShouldRun", VerboseLevel.Obnoxious, _
      '              "ShouldRun not useful for ProcessNodeset for " & outputFileName)
      '      Return True
      '   Else
      '      Return ShouldRun(outputFileName, Me.GetGenType(node), _
      '               Me.GetHashWhitespace(node), Me.GetOutType(node), _
      '               statusoutput)
      '   End If
      'End Function

      ''' <summary>
      ''' 
      ''' </summary>
      ''' <param name="outputFileName"></param>
      ''' <param name="genType"></param>
      ''' <param name="hashWhitespace"></param>
      ''' <param name="outType"></param>
      ''' <param name="statusoutput"></param>
      ''' <returns></returns>
      ''' <remarks>Same as SHouldRun, just name change to make shared</remarks>
      Public Shared Function ShouldCreateStream( _
               ByVal outputFileName As String, _
               ByVal genType As CodeGenerationSupport.OutputGenType, _
               ByVal hashWhitespace As CodeGenerationSupport.HashWhitespace, _
               ByVal outType As CodeGenerationSupport.OutputFileType, _
               ByVal statusoutput As IStatusOutput) _
               As Boolean
         Dim fileChanged As Utility.FileChanged
         fileChanged = Utility.HashTools.IsFileChanged(outputFileName, _
                                 outType.ToString, _
                                 Settings.GetCommentStart(outType), _
                                 Settings.GetCommentEnd(outType), _
                                 Settings.GetHeaderMarker(), _
                                 Settings.GetFullHashMarker(), _
                                 Settings.GetSemanticHashMarker(), _
                                 Settings.GetNoWSHashMarker())
         Return ShouldRun(genType, hashWhitespace, fileChanged, outputFileName, False, statusoutput)
      End Function

      Public Function ShouldRun( _
                     ByVal outputFileName As String, _
                     ByVal genType As CodeGenerationSupport.OutputGenType, _
                     ByVal hashWhitespace As CodeGenerationSupport.HashWhitespace, _
                     ByVal outType As CodeGenerationSupport.OutputFileType, _
                     ByVal statusoutput As IStatusOutput) _
                     As Boolean
         Dim fileChanged As Utility.FileChanged
         If mProjectSettings Is Nothing Then
            fileChanged = Utility.HashTools.IsFileChanged(outputFileName, _
                                 outType.ToString, _
                                 Settings.GetCommentStart(outType), _
                                 Settings.GetCommentEnd(outType), _
                                 Settings.GetHeaderMarker(), _
                                 Settings.GetFullHashMarker(), _
                                 Settings.GetSemanticHashMarker(), _
                                 Settings.GetNoWSHashMarker())
         Else
            fileChanged = Utility.HashTools.IsFileChanged(outputFileName, _
                                 outType.ToString, _
                                 mProjectSettings.GetCommentStart(outType), _
                                 mProjectSettings.GetCommentEnd(outType), _
                                 mProjectSettings.GetHeaderMarker(), _
                                 mProjectSettings.GetFullHashMarker(), _
                                 Settings.GetSemanticHashMarker(), _
                                 mProjectSettings.GetNoWSHashMarker())
         End If
         Return ShouldRun(genType, hashWhitespace, fileChanged, outputFileName, False, statusoutput)
      End Function

      Private Shared Function ShouldRun( _
                     ByVal genType As CodeGenerationSupport.OutputGenType, _
                     ByVal hashWhitespace As CodeGenerationSupport.HashWhitespace, _
                     ByVal fileChanged As Utility.FileChanged, _
                     ByVal outputFileName As String, _
                     ByVal isRunSQLScript As Boolean, _
                     ByVal status As IStatusOutput) _
                     As Boolean
         Dim sMode As String = ""
         If isRunSQLScript Then
            sMode = "(Running SQL Script) "
         End If
         Select Case genType
            Case CodeGenerationSupport.OutputGenType.Overwrite
               Return True
            Case CodeGenerationSupport.OutputGenType.Always
               Select Case fileChanged
                  Case fileChanged.Unknown
                     status.AddStatusFailure("RunUtility.ShouldRun", _
                              sMode & "Autogenerated hash could not be recovered. " & _
                              "Generation of " & outputFileName & " aborted:" & outputFileName, Nothing)
                     status.FileTreatment = FileTreatment.NewFileNotSaved
                  Case Utility.FileChanged.Changed
                     status.AddStatusFailure("RunUtility.ShouldRun", _
                              sMode & "Autogenerated file was manually edited. " & _
                              "Generation of " & outputFileName & " aborted" & outputFileName, Nothing)
                     status.FileTreatment = FileTreatment.NewFileNotSaved
                  Case Utility.FileChanged.NotSemantic
                     If hashWhitespace = hashWhitespace.Semantic Or _
                              hashWhitespace = hashWhitespace.ExcludeWhitespace Then
                        Return True
                     Else
                        status.AddStatusFailure("RunUtility.ShouldRun", _
                                 sMode & "Semantic changes have been made manually in this file. " & _
                                 "Generation of " & outputFileName & " aborted:" & outputFileName, Nothing)
                        status.FileTreatment = FileTreatment.NewFileNotSaved
                     End If
                  Case Utility.FileChanged.WhitespaceOnly
                     If hashWhitespace = hashWhitespace.ExcludeWhitespace Then
                        Return True
                     Else
                        status.AddStatusFailure("RunUtility.ShouldRun", _
                                 sMode & "Whitespace has been manually changed in this file. " & _
                                 "Generation of " & outputFileName & " aborted:" & outputFileName, Nothing)
                        status.FileTreatment = FileTreatment.NewFileNotSaved
                     End If
                  Case Else
                     Return True
               End Select
            Case CodeGenerationSupport.OutputGenType.Unknown
               ' I have no idea why we'd be here
            Case CodeGenerationSupport.OutputGenType.Once
               Select Case fileChanged
                  Case Utility.FileChanged.FileDoesntExist
                     Return True
                  Case Else
                     status.AddStatusInfo("RunUtility.ShouldRun", VerboseLevel.Reserved, _
                              sMode & outputFileName & _
                              " not generated because it already existed. " & _
                              "This could be a normal condition." & outputFileName)
               End Select
            Case CodeGenerationSupport.OutputGenType.UntilEdited
               Select Case fileChanged
                  Case Utility.FileChanged.FileDoesntExist, _
                              Utility.FileChanged.NotChanged
                     Return True
                  Case Utility.FileChanged.Unknown
                     ' I'm not sure whether this should be a warning or error
                     status.AddStatusFailure("RunUtility.ShouldRun", _
                              sMode & "Autogenerated hash could not be recovered. " & _
                              "Generation of " & outputFileName & " aborted :" & outputFileName, Nothing)
                  Case Utility.FileChanged.Changed
                     status.AddStatusInfo("RunUtility.ShouldRun", VerboseLevel.Reserved, _
                            "File not generated because it existed and had been edited. ")
               End Select
         End Select
         Return False
      End Function

      Private Function GetNameSpaceManager( _
                     ByVal xmlDoc As Xml.XmlDocument, _
                     ByVal prefix As String) _
                     As Xml.XmlNamespaceManager
         Dim nsmgr As New Xml.XmlNamespaceManager(xmlDoc.NameTable)
         Dim ns As String = Nothing
         Select Case prefix
            Case "kg"
               ns = "http://kadgen.com/KADGenDriving.xsd"
            Case "dbs"
               ns = "http://kadgen/DatabaseStructure"
         End Select
         If Not ns Is Nothing Then
            nsmgr.AddNamespace(prefix, ns)
            Return nsmgr
         End If
         Return Nothing
      End Function

      Private Function GetOutType( _
                     ByVal node As Xml.XmlNode) _
                     As CodeGenerationSupport.OutputFileType
         Dim outTypeString As String
         Dim nsmgr As Xml.XmlNamespaceManager = GetNameSpaceManager( _
                              node.OwnerDocument, _
                              "kg")
         Dim nodeStandard As Xml.XmlNode = node.SelectSingleNode( _
                              "kg:OutputRules", nsmgr)
         outTypeString = Utility.Tools.GetAttributeOrEmpty( _
                              nodeStandard, "OutputFileType")
         If outTypeString.Trim.Length = 0 Then
            Return CodeGenerationSupport.OutputFileType.Unknown
         Else
            Return CType(System.Enum.Parse(GetType(CodeGenerationSupport.OutputFileType), _
                              outTypeString), CodeGenerationSupport.OutputFileType)
         End If
      End Function

      Private Function GetApplyHash(ByVal node As Xml.XmlNode) As String
         Dim nsmgr As Xml.XmlNamespaceManager = Utility.xmlHelpers.BuildNameSpaceManager( _
                        node, "kg", False)
         Return Utility.Tools.GetAttributeOrEmpty(node, "kg:OutputRules", _
                              "HashOutput", nsmgr)
      End Function

      Private Function GetGenType( _
                  ByVal node As Xml.XmlNode) _
                  As CodeGenerationSupport.OutputGenType
         Dim genTypeString As String
         Dim nsmgr As Xml.XmlNamespaceManager = _
                              GetNameSpaceManager(node.OwnerDocument, _
                              "kg")
         Dim nodeStandard As Xml.XmlNode = node.SelectSingleNode( _
                              "kg:OutputRules", nsmgr)
         genTypeString = Utility.Tools.GetAttributeOrEmpty(nodeStandard, _
                              "OutputGenType")
         Return CType(System.Enum.Parse(GetType(CodeGenerationSupport.OutputGenType), genTypeString), _
                              CodeGenerationSupport.OutputGenType)
      End Function

      Private Function GetHashWhitespace( _
                  ByVal node As Xml.XmlNode) _
                  As HashWhitespace
         Dim genHashWhitespace As String
         Dim nsmgr As Xml.XmlNamespaceManager = _
                              GetNameSpaceManager(node.OwnerDocument, _
                              "kg")
         Dim nodeOutput As Xml.XmlNode = node.SelectSingleNode( _
                              "kg:OutputRules", nsmgr)
         genHashWhitespace = Utility.Tools.GetAttributeOrEmpty(nodeOutput, _
                              "HashWhitespace")
         Return CType(System.Enum.Parse(GetType(CodeGenerationSupport.HashWhitespace), genHashWhitespace), _
                              CodeGenerationSupport.HashWhitespace)

      End Function

      Public Overridable Function SSCheckOutFile( _
                   ByVal checkOut As Boolean, _
                   ByVal checkOutProject As String, _
                   ByVal file As String, _
                   ByVal statusoutput As IStatusOutput) _
                   As Utility.SourceControlBase.ItemStatus
         Const source As String = "RunUtility.SSCheckOutFile"
         Dim status As Utility.SourceControlBase.ItemStatus
         If checkOut Then
            statusoutput.AddStatusInfo(source, VerboseLevel.Talkative, _
                     "Checking out file " & file & " from SS Project " & checkOutProject)
            If (Not checkOutProject Is Nothing) AndAlso _
                        checkOutProject.Trim.Length > 0 Then
               If mSourceControl Is Nothing Then
                  ' TODO: Figure out whether this is an error
                  Return Utility.SourceControlBase.ItemStatus.NoSourceControl
               Else
                  status = mSourceControl.CheckOut(file, "", checkOutProject)
                  If status = Utility.SourceControlBase.ItemStatus.NotCheckedOutToMe Then
                     statusoutput.AddStatusFailure(source, _
                                 "Couldn't check file out of SourceSafe:" & file, Nothing)
                  End If
                  Return status
               End If
            End If
            statusoutput.AddStatusInfo(source, VerboseLevel.Reserved, _
                    "ItemStatus after checkout attempt" & status.ToString)
         Else
            statusoutput.AddStatusInfo(source, VerboseLevel.Obnoxious, _
                     "Checkout Not Requested for file " & file)
            Return Utility.SourceControlBase.ItemStatus.CheckoutNotRequested
         End If
      End Function

      Public Overridable Sub SSCheckInFile( _
                     ByVal checkOut As Boolean, _
                     ByVal checkOutProject As String, _
                     ByVal file As String, _
                     ByVal addFile As Boolean, _
                     ByVal itemStatus As Utility.SourceControlBase.ItemStatus, _
                   ByVal OutputStatus As IStatusOutput)
         If (Not checkOutProject Is Nothing) AndAlso _
                     checkOutProject.Trim.Length > 0 Then
            If mSourceControl Is Nothing Then
               ' TODO: Figure out whether this is an error
            Else
               mSourceControl.CheckIn(file, "", checkOutProject, itemStatus, addFile)
            End If
         End If
      End Sub

      Public Function MarkWriteAndClose( _
                   ByVal stream As IO.Stream, _
                   ByVal outType As CodeGenerationSupport.OutputFileType, _
                   ByVal genType As CodeGenerationSupport.OutputGenType, _
                   ByVal applyHash As Boolean, _
                   ByVal outputFile As String, _
                   ByVal statusoutput As CodeGenerationSupport.IStatusOutput) _
                   As Boolean
         Dim writer As IO.StreamWriter
         Dim reader As IO.StreamReader
         Dim madeFile As Boolean = stream.Length > 0
         If Not madeFile Then
            statusoutput.FileTreatment = FileTreatment.NoNewFile
         Else
            If applyHash Then
               stream = Utility.HashTools.ApplyHash(stream, _
                                 outType.ToString, _
                                 mProjectSettings.GetCommentText(genType), _
                                 mProjectSettings.GetCommentStart(outType), _
                                 mProjectSettings.GetCommentEnd(outType), _
                                 mProjectSettings.GetHeaderMarker(), _
                                 mProjectSettings.GetFullHashMarker(), _
                                 mProjectSettings.GetSemanticHashMarker(), _
                                 mProjectSettings.GetNoWSHashMarker())
            End If
            Utility.Tools.MakePathIfNeeded(outputFile)
            writer = New IO.StreamWriter(outputFile)
            reader = New IO.StreamReader(stream)
            stream.Seek(0, IO.SeekOrigin.Begin)
            writer.Write(reader.ReadToEnd)
            writer.Flush()
            writer.Close()
            reader.Close()
            statusoutput.FileTreatment = FileTreatment.Overwritten
         End If
         Return madeFile
      End Function

      Public Function BuildParamArray( _
               ByVal params As CodeGenerationSupport.XSLTParam()) _
               As Object()
         Dim ret() As Object = {}
         If Not params Is Nothing Then
            ReDim ret(params.GetUpperBound(0))
            For i As Int32 = 0 To params.GetUpperBound(0)
               ret(i) = params(i).Value
            Next
         End If
         Return ret
      End Function

      Public Function IsTextChanged( _
               ByVal text As String, _
               ByVal outputType As CodeGenerationSupport.OutputFileType) _
               As Utility.FileChanged
         Return Utility.HashTools.IsTextChanged(text, _
                     outputType.ToString, _
                     mProjectSettings.GetCommentStart(outputType), _
                     mProjectSettings.GetCommentEnd(outputType), _
                     mProjectSettings.GetHeaderMarker(), _
                     mProjectSettings.GetFullHashMarker(), _
                     mProjectSettings.GetSemanticHashMarker(), _
                     mProjectSettings.GetNoWSHashMarker())
      End Function

      Public Function ApplyHash( _
               ByVal text As String, _
               ByVal genType As CodeGenerationSupport.OutputGenType, _
               ByVal outType As CodeGenerationSupport.OutputFileType) _
               As String
         Return Utility.HashTools.ApplyHash(text, _
                  outType.ToString, _
                  mProjectSettings.GetCommentText(genType), _
                  mProjectSettings.GetCommentStart(outType), _
                  mProjectSettings.GetCommentEnd(outType), _
                  True, mProjectSettings.GetHeaderMarker(), _
                  mProjectSettings.GetFullHashMarker(), _
                  mProjectSettings.GetSemanticHashMarker(), _
                  mProjectSettings.GetNoWSHashMarker())
      End Function

      Public Shared Function ParseFilenamePattern( _
                  ByVal fileName As String, _
                  ByVal node As Xml.XmlNode, _
                  ByVal nsmgr As Xml.XmlNamespaceManager) _
                  As String
         Dim xPath As String
         Dim iStart As Int32
         Dim iEnd As Int32
         Dim sEnd As String
         Dim fragNode As Xml.XmlNode
         Do While fileName.IndexOf("<") >= 0
            iStart = fileName.IndexOf("<")
            iEnd = fileName.IndexOf(">")
            xPath = fileName.Substring(iStart + 1, iEnd - iStart - 1)
            If xPath.IndexOf("<") >= 0 Then
               xPath = ParseFilenamePattern(xPath, node, nsmgr)
            End If
            ' *Changed to pass nsmgr 7/27/03 KD
            'Dim nsmgr As Xml.XmlNamespaceManager = GetNameSpaceManager(node.OwnerDocument, "dbs")
            fragNode = node.SelectSingleNode(xPath, nsmgr)
            sEnd = fileName.Substring(iEnd + 1)
            fileName = fileName.Substring(0, iStart)
            If Not fragNode Is Nothing Then
               fileName &= fragNode.Value
            End If
            fileName &= sEnd
         Loop
         Return fileName
      End Function

      Public Sub OutputWithRule( _
               ByVal directiveStatus As IStatusDirective, _
               ByVal outputFileName As String, _
               ByVal outputRUle As IOutputRuleSupportElement, _
               ByVal processToRun As OutputWithRuleDelegate, _
               ByVal args As RunArgs)
         Dim itemstatus As Utility.SourceControlBase.ItemStatus
         Dim stream As IO.Stream = Nothing
         Dim statusoutput As IStatusOutput = directiveStatus.AddStatusOutput( _
                 outputFileName, _
                 FileTreatment.Unknown)
         Try
            If Me.ShouldRun(outputFileName, _
                     outputRUle.OutputGenType, _
                     outputRUle.HashWhitespace, _
                     outputRUle.OutputFileType, statusoutput) Then
               Dim madeFile As Boolean
               Try
                  stream = processToRun.Invoke(args)
               Catch ex As System.Exception
                  statusoutput.AddStatusException("CreateMetadata.Run", "Failure creating SQL XML output", ex)
               End Try
               If Not stream Is Nothing Then
                  Utility.Tools.MakePathIfNeeded(outputFileName)
                  madeFile = Me.MarkWriteAndClose( _
                           stream, _
                           outputRUle.OutputFileType, _
                           outputRUle.OutputGenType, _
                           outputRUle.HashOutput, _
                           outputFileName, statusoutput)
               End If
               directiveStatus.CountCreated += 1
               directiveStatus.Status = statusoutput.ChildStatus
               If madeFile Then
                  directiveStatus.CountOutput += 1
               End If
            End If
            directiveStatus.CountOutput = 1
         Catch ex As System.Exception
            statusoutput.AddStatusException("MorphMetadata.Run", "Failure creating file", ex)
         End Try
         statusoutput.Status = statusoutput.ChildStatus
      End Sub
      'Private Sub SetProcess( _
      '               ByVal node As Xml.XmlNode, _
      '               ByVal nsmgr As Xml.XmlNamespaceManager)
      '   SetProcess(node, nsmgr, "kg:Process")
      'End Sub

      'Private Sub SetProcess( _
      '              ByVal node As Xml.XmlNode, _
      '              ByVal nsmgr As Xml.XmlNamespaceManager, _
      '              ByVal elementName As String)
      '   Dim paramInfos() As Reflection.ParameterInfo
      '   mMethodInfo = Utility.Tools.GetMethodInfo(node, _
      '               GetType(Generation), _
      '               nsmgr, _
      '               elementName, _
      '               mLocalSettings.GetBasePath(), _
      '               mDocPath, _
      '               mNodeFilePaths)
      '   If Not mMethodInfo Is Nothing Then
      '      paramInfos = mMethodInfo.GetParameters
      '      ReDim mParams(paramInfos.GetUpperBound(0))
      '      For i As Int32 = 0 To paramInfos.GetUpperBound(0)
      '         mParams(i) = New CodeGenerationSupport.XSLTParam(paramInfos(i).Name)
      '      Next
      '   End If
      'End Sub

      'Private Function ParseFilenamePattern( _
      '                  ByVal fileName As String, _
      '                  ByVal node As Xml.XmlNode, _
      '                  ByVal nsmgr As Xml.XmlNamespaceManager) _
      '                  As String
      '   Dim xPath As String
      '   Dim iStart As Int32
      '   Dim iEnd As Int32
      '   Dim sEnd As String
      '   Dim fragNode As Xml.XmlNode
      '   Do While fileName.IndexOf("<") >= 0
      '      iStart = fileName.IndexOf("<")
      '      iEnd = fileName.IndexOf(">")
      '      xPath = fileName.Substring(iStart + 1, iEnd - iStart - 1)
      '      If xPath.IndexOf("<") >= 0 Then
      '         xPath = ParseFilenamePattern(xPath, node, nsmgr)
      '      End If
      '      ' *Changed to pass nsmgr 7/27/03 KD
      '      'Dim nsmgr As Xml.XmlNamespaceManager = GetNameSpaceManager(node.OwnerDocument, "dbs")
      '      fragNode = node.SelectSingleNode(xPath, nsmgr)
      '      sEnd = fileName.Substring(iEnd + 1)
      '      fileName = fileName.Substring(0, iStart)
      '      If Not fragNode Is Nothing Then
      '         fileName &= fragNode.Value
      '      End If
      '      fileName &= sEnd
      '   Loop
      '   Return fileName
      'End Function

      'Public Sub MultiPass( _
      '   ByVal node As Xml.XmlNode, _
      '   ByVal nsmgr As Xml.XmlNamespaceManager, _
      '   ByVal multiPass As CodeGenerationSupport.IMultiPassSupportElement, _
      '   ByVal outputRule As CodeGenerationSupport.IOutputRuleSupportElement, _
      '   ByVal xmlMetadata As Xml.XmlDocument, _
      '   ByVal xmlMetadataFileName As String, _
      '   ByVal delegGenerate As GenerateDelegate, _
      '   ByVal statusDirective As CodeGenerationSupport.IStatusDirective)
      '   Dim selectFileName As String
      '   Dim xmlSelect As New Xml.XmlDocument
      '   Dim nodeList As Xml.XmlNodeList
      '   Dim outputFileName As String
      '   Dim statusOutput As CodeGenerationSupport.IStatusOutput
      '   Dim nsMgrMeta As Xml.XmlNamespaceManager

      '   Dim attr As Xml.XmlNode
      '   Dim stream As IO.Stream

      '   Dim madeFile As Boolean
      '   Dim itemstatus As Utility.SourceControlBase.ItemStatus
      '   selectFileName = multiPass.SelectFile.Trim
      '   If Not selectFileName Is Nothing AndAlso selectFileName.Length > 0 Then
      '      If (Not xmlMetadata Is Nothing And _
      '                  Not xmlMetadataFileName Is Nothing) AndAlso _
      '               xmlMetadataFileName = selectFileName Then
      '         xmlSelect = xmlMetadata
      '      Else
      '         If (Not mSelectXML Is Nothing And _
      '                     Not mSelectXMLFileName Is Nothing) AndAlso _
      '                  mSelectXMLFileName = selectFileName Then
      '            xmlSelect = mSelectXML
      '         Else
      '            ' Well, add it
      '            xmlSelect = New Xml.XmlDocument
      '            xmlSelect.Load(multiPass.SelectFile)
      '            mSelectXML = xmlSelect
      '            mSelectXMLFileName = multiPass.SelectFile
      '         End If
      '      End If
      '      nodeList = xmlSelect.SelectNodes(multiPass.SelectXPath, nsMgrMeta)
      '      statusDirective.CountSelected = nodeList.Count
      '      For Each nodeSelect As Xml.XmlNode In nodeList
      '         madeFile = False
      '         outputFileName = IO.Path.Combine( _
      '                     ParseFilenamePattern(multiPass.OutputDir, nodeSelect, nsMgrMeta), _
      '                     ParseFilenamePattern(multiPass.OutputFilePattern, nodeSelect, nsMgrMeta))
      '         statusDirective.CurrentFileName = outputFileName
      '         statusOutput = statusDirective.AddStatusOutput( _
      '                  OutputStatus.InProgress, outputFileName, _
      '                  FileTreatment.Unknown)
      '         Utility.Tools.MakePathIfNeeded(outputFileName)
      '         If Me.ShouldRun(outputFileName, outputRule.OutputGenType, _
      '                 outputRule.OutputFileType, statusOutput) Then
      '            itemstatus = Me.SSCheckOutFile( _
      '                  outputRule.CheckOut, _
      '                  outputRule.CheckOutProject, _
      '                  node, outputFileName, statusOutput)
      '            If itemstatus <> Utility.SourceControlBase.ItemStatus.NotCheckedOutToMe Then
      '               Try
      '                  stream = delegGenerate.Invoke(outputFileName, nsmgr, node, _
      '                                     nodeSelect)
      '                  If Not stream Is Nothing Then
      '                     madeFile = MarkWriteAndClose(stream, node, outputFileName)
      '                  End If
      '                  statusDirective.CountCreated += 1
      '                  If madeFile Then
      '                     statusDirective.CountOutput += 1
      '                  End If
      '               Finally
      '                  Me.SSCheckInFile( _
      '                           outputRule.CheckOut, _
      '                           outputRule.CheckOutProject, _
      '                           node, outputFileName, True, itemstatus, statusOutput)
      '               End Try
      '            End If
      '         End If
      '      Next
      '      statusDirective.Status = OutputStatus.Success
      '   End If
      'End Sub


   End Class


End Namespace